<template>
  <!-- 不是行内form 行内inline=true -->
  <el-form label-width="80px" :model="spuInfo">
    <el-form-item label="SPU名称">
      <el-input v-model="spuInfo.spuName"></el-input>
    </el-form-item>
    <el-form-item label="品牌">
      <el-select placeholder="请选择品牌" v-model="spuInfo.tmId">
        <el-option
          :label="trademark.tmName"
          :value="trademark.id"
          v-for="(trademark, index) in trademarkList"
          :key="trademark.id"
        ></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="SUP描述" value="">
      <el-input type="textarea" v-model="spuInfo.description"></el-input>
    </el-form-item>
    <!-- 照片墙 -->
    <el-form-item label="SPU图片">
      <!-- 
        action:上传图片的地址
        list-type:照片墙的烈性
        on-preview:放大属性(预览的钩子)
        on-remove:删除的钩子
        on-success:图片上传成功的回调
        file-list:照片墙需要展示数据的设置属性,数组,数组里面的元素要有name(图片的名字)与url(图片的地址)属性
       -->
      <el-upload
        action="/dev-api/admin/product/fileUpload"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :file-list="spuImageList"
        :on-success="handlerSuccess"
      >
        <i class="el-icon-plus"></i>
      </el-upload>
      <el-dialog :visible.sync="dialogVisible">
        <img width="100%" :src="dialogImageUrl" alt="" />
      </el-dialog>
    </el-form-item>
    <!-- 销售属性 -->
    <el-form-item label="销售属性">
      <!-- 展示的是当前这个类未选择的销售属性 -->
      <el-select
        :placeholder="
          unSelectSaleAttr.length > 0
            ? `还有${unSelectSaleAttr.length}个没选择`
            : '没了'
        "
        v-model="saleAttrIdAndName"
      >
        <!-- el-option:value是收集下拉框的 数据 -->
        <el-option
          :label="saleAttr.name"
          :value="`${saleAttr.id}:${saleAttr.name}`"
          v-for="(saleAttr, index) in unSelectSaleAttr"
          :key="saleAttr.id"
        ></el-option>
      </el-select>
      <el-button
        type="primary"
        icon="el-icon-plus"
        :disabled="!saleAttrIdAndName"
        @click="addSaleAttr"
        >添加销售属性</el-button
      >
      <!--  -->
      <el-table
        style="width: 100%; margin-top: 10px"
        border
        :data="spuInfo.spuSaleAttrList"
      >
        <el-table-column type="index" width="80px" align="center" label="序号">
        </el-table-column>
        <el-table-column prop="saleAttrName" label="属性名" width="150px">
        </el-table-column>
        <el-table-column label="属性值名称列表" width="width">
          <template slot-scope="{ row, $index }">
            <!-- 
              el-tag:
                closable是否可以关闭
                disable-transitions过渡动画
                close:关闭tag的事件
                @close="handleClose(tag)"
             -->
            <el-tag
              :key="saleAttrValue.id"
              v-for="(saleAttrValue, index) in row.spuSaleAttrValueList"
              closable
              hit
              @close="row.spuSaleAttrValueList.splice(index, 1)"
              :disable-transitions="false"
            >
              {{ saleAttrValue.saleAttrValueName }}
            </el-tag>
            <!-- 查看与编辑模式的切换 -->
            <el-input
              class="input-new-tag"
              v-if="row.show"
              v-model="row.inputValue"
              ref="saveTagInput"
              size="small"
              @keyup.enter.native="toLook(row)"
              @blur="toLook(row)"
            >
            </el-input>
            <el-button
              v-else
              hit
              class="button-new-tag"
              size="small"
              @click="toEdit(row)"
              >添加</el-button
            >
          </template>
        </el-table-column>
        <el-table-column label="操作" width="150px">
          <template slot-scope="{ row, $index }">
            <el-button
              type="danger"
              icon="el-icon-delete"
              size="mini"
              @click="spuInfo.spuSaleAttrList.splice($index, 1)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="addOrUpdate">保存</el-button>
      <el-button @click="changeScene">取消</el-button>
    </el-form-item>
    <h1>{{ unSelectSaleAttr }}</h1>
  </el-form>
</template>

<script>
export default {
  name: "SpuForm",
  data() {
    return {
      // 照片墙的属性
      dialogImageUrl: "",
      dialogVisible: false,
      // 存储当前类的信息
      spuInfo: {
        category3Id: "", //三级分类的ID
        spuName: "", //收集SPU的名字
        tmId: "", //收集品牌的ID
        description: "", //收集类的描述信息
        spuImageList: [
          // {
          //   imgName: "", //图片的名字
          //   imgUrl: "", //图片的地址
          // },
        ],

        spuSaleAttrList: [
          //销售属性地方
          // {
          //   baseSaleAttrId: "", //销售属性的ID
          //   saleAttrName: "", //销售属性的名字
          //   spuSaleAttrValueList: [
          //     //销售属性值的地方
          //     {
          //       baseSaleAttrId: 0, //当前销售属性值属于哪一个销售属性的
          //       saleAttrValueName: "", //销售属性值的名字
          //     },
          //   ],
          // },
        ],
      },
      // 存储照片墙的数据
      spuImageList: [],
      // 存储品牌的数据
      trademarkList: [],
      // 存储销售属性的数据
      attrList: [],
      // 收集销售属性的id与销售属性的值
      saleAttrIdAndName: "",
    };
  },
  methods: {
    // 图片上传成功的回调
    handlerSuccess(response, file, fileList) {
      // response:图片上传成功以后,服务器返回的相依的数据(包含远程图片的地址)
      // file  :图片上传后的信息 图片信息
      // fileList: 图片上传成功以后,照片墙一共有的信息
      this.spuImageList = fileList;
    },
    //   删除
    handleRemove(file, fileList) {
      // 当照片删除的时候就会触发--收集
      // fileList:删除那张照片的信息
      // fileList:照片墙删除某一张照片之后剩余其他图片--(收集:数据里面name,url不要),最后整理
      this.spuImageList = fileList;
    },
    //预览
    handlePictureCardPreview(file) {
      // 当用户点击照片墙的预览按钮就会触发,file形参就会注入的,看到图片信息(图片的地址名字)
      // 当点击预览按钮的时候,对话框展示出来,以及vc保存选中这张图片的路径,在对话框的img中显示
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    // 点击取消的回调函数
    changeScene() {
      // 触发自定义事件
      this.$emit("changeScene", {scene:0,flag:'修改'});
      // 清空数据
      // this.$options能获取当前VC的配置对象
      Object.assign(this._data, this.$options.data());
    },
    async initData(spuId) {
      // 第一个请求:通过类的id获取当前修改类的信息
      let promise1 = this.$ajax.spu.reqSpuById(spuId);
      // 第二个请求:通过类的id,获取照片墙的数据
      let promise2 = this.$ajax.spu.reqSpuImageList(spuId);
      // 第三个请求:获取品牌的数据
      let promise3 = this.$ajax.spu.reqTrademarkList();
      // 第四个请求:获取整个项目的全部的销售属性
      let promise4 = this.$ajax.spu.reqSaleAttrList();
      // 利用Promise.all获取全部返回成功的数据
      let arr = await Promise.all([promise1, promise2, promise3, promise4]);
      // 赋值
      // spu类的信息数据
      this.spuInfo = arr[0].data;
      // 照片墙的数据
      this.spuImageList = arr[1].data;
      // 由于照片墙的数据格式需要有name与字段,而服务器返回的数据中不带有,因此需要'进行修改'
      this.spuImageList = this.spuImageList.map((item) => {
        // 作为新的数据的元素,Es6拓展运算符
        return {
          ...item,
          url: item.imgUrl,
          name: item.imgName,
        };
      });
      // 品牌数据
      this.trademarkList = arr[2].data;
      // 全部销售属性
      this.attrList = arr[3].data;
    },
    // el-input 的事件回调--变为查看模式
    toLook(row) {
      // 结构出想要的数据[当前类的id,新增的属性的属性值]
      const { baseSaleAttrId, inputValue } = row;

      // 第一种情况新增的属性值不能为空的
      if (inputValue.trim() == "") {
        this.$message({
          type: "error",
          message: "不可输入空内容",
        });
        return;
      }

      // 第二种情况:新增的属性值不能有
      let repeat = row.spuSaleAttrValueList.find((item) => {
        return item.saleAttrValueName == inputValue;
      });
      if (repeat) {
        this.$message({
          type: "error",
          message: "不可输重复内容",
        });
        return;
      }

      // 整理销售属性值的数据格式[文档:后台需要的格式]
      let newSaleAttrValue = {
        baseSaleAttrId,
        saleAttrValueName: inputValue,
      };
      // 新增销售属性值
      row.spuSaleAttrValueList.push(newSaleAttrValue);
      // 修改已经有的响应式的属性的属性值
      row.show = false;
    },
    // toEdit(添加按钮的回调) --变为编辑模式
    toEdit(row) {
      // 给每一个销售属性新增响应式数据[控制查看与编辑]
      // 第一个参数;那个对象,第二;属性;第三参数
      this.$set(row, "show", true); //用来切换模式[编辑模式与查看模式]
      this.$set(row, "inputValue", ""); //用来收据输入的销售属性的属性值
      // 聚焦
      this.$nextTick(() => {
        this.$refs.saveTagInput.focus();
      });
    },

    // 新增|修改  保存按钮
    async addOrUpdate() {
      // 整理参数
      // 照片墙的数据需要整理
      // 照片对象:服务器只需要imageName||imageUrl,不需要name和url
      this.spuInfo.spuImageList = this.spuImageList.map((item) => {
        return {
          imageName: item.name,
          imgUrl: (item.response && item.response.data) || item.url,
        };
      });
      // 发请求
      try {
        // 保存成功
        await this.$ajax.spu.reqAddOrUpdateSpu(this.spuInfo);
        // 成功提示
        this.$message({ type: "success", message: "保存成功" });
        //保存成功[添加|修改],通知父组件切换场景为0
        this.$emit("changeScene", {
          scene: 0,
          flag:this.spuInfo.id?'修改':'新增',
        });
        // 清空数据
        Object.assign(this._data, this.$options.data());
      } catch (error) {}
    },
    //
    addSaleAttr() {
      // 获取新增的销售属性Id与名字[3.'尺寸']
      let [baseSaleAttrId, saleAttrName] = this.saleAttrIdAndName.split(":");
      // 整理新增的销售属性
      let newSaleAttr = {
        baseSaleAttrId,
        saleAttrName,
        spuSaleAttrValueList: [],
      };
      // 添加数组里面
      this.spuInfo.spuSaleAttrList.push(newSaleAttr);
      // 清空字符串
      this.saleAttrIdAndName = "";
    },
    // 当点击添加SPU的按钮的回调,父组件调用这个方法
   async initAddSpuData(category3Id){
    //  收集父组件传递三级分类的id
    this.spuInfo.category3Id=category3Id;
       // 第1个请求:获取品牌的数据
      let promise1 = this.$ajax.spu.reqTrademarkList();
      // 第2个请求:获取整个项目的全部的销售属性
      let promise2 = this.$ajax.spu.reqSaleAttrList();
      // 利用Promise.all获取全部返回成功的数据
      let arr = await Promise.all([promise1, promise2]);
      this.trademarkList=arr[0].data;
      this.attrList=arr[1].data;
    }
  },
  computed: {
    // 计算属性
    unSelectSaleAttr() {
      // 全部的销售属性3个
      // console.log(this.attrList);
      // 当前已有的销售属性
      // console.log(this.spuInfo.spuSaleAttrList);

      let result = this.attrList.filter((item) => {
        return this.spuInfo.spuSaleAttrList.every((item1) => {
          return item.name != item1.saleAttrName;
        });
      });
      return result;
    },
  },
};
</script>

<style>
.el-tag + .el-tag {
  margin-left: 10px;
}
.button-new-tag {
  margin-left: 10px;
  height: 32px;
  line-height: 30px;
  padding-top: 0;
  padding-bottom: 0;
}
.input-new-tag {
  width: 90px;
  margin-left: 10px;
  vertical-align: bottom;
}
</style>